#include <stdio.h>
#include <mm_malloc.h>
#include <string.h>
#define MAX 999         //监督元
#define n 4             //n个叶子节点
char s[6]={0};          //存放哈夫曼编码的数组，初始化
typedef struct Hfnode
{
    int data;           //权值
    char hfcode[6];     //哈夫曼编码
    struct Hfnode *Lson,*Rson,*next;
}Hfnode,*Hfptr;

//初始化函数
Hfptr inition()
{
    int i;Hfptr h,p;
    h=p=(Hfptr)malloc(sizeof(Hfnode));
    h->data=MAX;
    for(i=1;i<=n;i++)
    {
        p->next=(Hfptr)malloc(sizeof(Hfnode));
        p=p->next;
        p->Lson=p->Rson=NULL;
        scanf("%d",&p->data);
    }
    p->next=h;
    return h;
}

//构建哈夫曼树
Hfptr creatHftree(Hfptr head)
{
    int i;Hfptr p,q,r,t1,t2;
    for(i=1;i<n;i++)
    {
        r=(Hfptr)malloc(sizeof(Hfnode));
        t1=head->next;
        t2=t1->next;
        r->data=t1->data+t2->data;       // 权值相加
        r->Lson=t1;
        r->Rson=t2;
        head->next=t2->next;
        q=head;
        p=head->next;
        while(1)                        //找相加后值的有序位置
        {
            if (p->data<r->data) {
                q=p;p=p->next;
            }
            else{
                r->next=p;
                q->next=r;
                break;
            }
        }
    }
    p=head->next;
    free(head);
    return (p);
}

//哈夫曼编码
int Hfcode(Hfptr p,int i,char code)
{
    int t,k,f;
    if (p==NULL) {
        return 0;
    }
    if (i>0) {
        s[i-1]=code;                   //在父节点的基础上添加新的编码（根节点不添加）
    }
    t=Hfcode(p->Lson, i+1, '0');      //走左传入0
    k=Hfcode(p->Rson, i+1, '1');      //走右传入1
    if (t==0&&k==0) {               //找到了叶子节点
        strcpy(p->hfcode,s);        // 填入哈夫曼编码
        printf("%d ",p->data);
        f=0;
        while (s[f]) {
            printf("%c",s[f]);      //打印数值并输出哈夫曼编码
            f++;
        }
        printf("\n");
        s[i-1]=0;                   //完成操作后将刚填入的编码置0，并返回上一层
        return 1;
    }
}

//主控函数
int main()
{
    int l;
    Hfptr Hfroot,head;
    head=inition();     //调用初始化函数
    Hfroot=creatHftree(head);//调用造树函数
    l=Hfcode(Hfroot,0,0);//输出哈夫曼编码
    return 0;
}